package com.cndw.kungfu.controller;

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import com.cndw.kungfu.comm.AccessFlag;
import com.cndw.kungfu.comm.tencent.LogFieldType;
import com.cndw.kungfu.comm.tencent.QQDC;
import com.cndw.kungfu.config.Constants;
import com.cndw.kungfu.config.ConstantsCost;
import com.cndw.kungfu.config.ConstantsDailyItem;
import com.cndw.kungfu.config.ConstantsDayIntKey;
import com.cndw.kungfu.config.ConstantsFlag;
import com.cndw.kungfu.config.ConstantsIntKey;
import com.cndw.kungfu.config.ConstantsLog;
import com.cndw.kungfu.config.ConstantsModel;
import com.cndw.kungfu.config.ConstantsTask;
import com.cndw.kungfu.domain.GoodsMode;
import com.cndw.kungfu.domain.LotteryLog;
import com.cndw.kungfu.domain.LotteryMode;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.ext.LangUtil;
import com.cndw.kungfu.ext.LanguageLib;
import com.cndw.kungfu.ext.LogUtil;
import com.cndw.kungfu.ext.NumberProcesser;
import com.cndw.kungfu.model.ActivitySerialize;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.activity.LotteryManager;
import com.cndw.kungfu.model.activity.domain.CarnivalConfig;
import com.cndw.kungfu.model.goods.PlayerBoxs;
import com.cndw.kungfu.model.sys.ChatMain;
import com.cndw.kungfu.model.sys.LogServer;
import com.cndw.kungfu.vo.goodsvo.GoodsVO;
import com.cndw.rpg.annotation.Controller;
import com.cndw.rpg.framework.ResponseMessage;
import com.cndw.rpg.framework.Session;

/**
 * 有关抽奖的接口
 * 
 * @author fantadust [9677889@qq.com]
 * @date 2012-2-21 下午7:54:48
 */
@AccessFlag(ConstantsFlag.lottery)
@Controller
public class LotteryController {
	@Autowired
	private LotteryManager lotteryManager;

	/**
	 * 显示物品
	 * 
	 * @param session
	 * @param type
	 * @return
	 */
	public ResponseMessage show(Session session, int type) {

		Collection<LotteryMode> modes = Context.getCongfigServer().getLotteryModes(type);
		if (modes == null) {
			return null;
		}
		List<GoodsVO> goods = new LinkedList<GoodsVO>();
		for (LotteryMode e : modes) {
			if (e.isHidden() || e.getGoodsId() == 0) {
				continue;
			}
			GoodsMode goodsMode = Context.getGoodsServer().getModeById(e.getGoodsId());
			if (goodsMode == null) {
				LogUtil.getMain().error("err id " + e.getGoodsId());
				continue;
			}
			GoodsVO vo = goodsMode.toGoodsVO();
			vo.setStackNum(e.getNum());
			goods.add(vo);
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("goods", goods);

		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Map<Integer, Integer> bag = player.getDataInfo().getLotteryBag(false);
		map.put("bagNum", bag == null ? 0 : bag.size());

		// Context.getTaskServer().notifyToSpark(session.getUid(),
		// ConstantsTask.spark28LotteryShow, 1);

		QQDC.getInstance().logClick(player, LogFieldType.lottey);

		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 显示抽奖记录
	 * 
	 * @param session
	 * @param type
	 *            抽奖类型
	 * @param isSelf
	 *            是否是自己的log
	 * @return
	 */
	public ResponseMessage log(Session session, int type, boolean isSelf) {
		List<LotteryLog> logs;
		if (type == 51) {
			logs = lotteryManager.getCarnivalLogsCache(false);
		} else if (isSelf) {
			logs = lotteryManager.getLotteryLogs(0, session.getUid(), 20, 0);
		} else {
			logs = lotteryManager.getLotteryLogs(0, 0, 20, 1);
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("logs", logs);
		map.put("isSelf", isSelf);
		map.put("type", type);

		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 进行抽奖
	 * 
	 * @param session
	 * @param type
	 * @param donType
	 * @return
	 */
	public ResponseMessage setAward(Session session, int type, int donType, int donNums) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		donNums = donType == 4 ? donNums : 1;
		if (donType >= 4 || donType <= 0 || donNums <= 0) {
			return null;
		}
		if (type <= 0 || type > 3) {
			return null;
		}
		int[] awardTimesArr = { 0, 1, 10, 50, donNums };
		Collection<LotteryMode> modes = Context.getCongfigServer().getLotteryModes(type);
		if (modes == null) {
			return null;
		}
		boolean isFirst = player.getDataInfo().intDataGet(ConstantsIntKey.firstLty) == 0;
		if (isFirst) {
			if (donType != 1) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("lottery.first.type"));
			} else if (!player.getPlayerBoxs().checkBlack()) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("lottery.first.black"));
			}
		}

		int awardTimes = awardTimesArr[donType];
		int costGold = ConstantsModel.lotteryGold[type - 1][donType - 1];
		int allGold = costGold;
		int useTools = 0;
		PlayerBoxs playerBoxs = player.getPlayerBoxs();
		if (type == 1) {
			int haveTools = playerBoxs.getStackNum(ConstantsModel.lotteryTools);
			useTools = haveTools <= awardTimes ? haveTools : awardTimes;
			costGold -= useTools * ConstantsModel.lotteryGold[type - 1][0];
		}

		if (costGold > 0) {
			if (player.getGoldAll() < costGold) {
				return ResponseMessage.getFailMessage(false);
			}
			player.alterGoldAll(-costGold);
			LogServer.costEventLog(player.getPlayerId(), costGold, ConstantsCost.lottery);
		}
		if (useTools > 0) {
			playerBoxs.costGoods(ConstantsModel.lotteryTools, useTools);
		}
		int maxLevel = 0;
		Map<Integer, Integer> awardsMap = new HashMap<Integer, Integer>();

		for (int i = 0; i < awardTimes; i++) {
			int tmpRate = NumberProcesser.mtRand(10000);
			int curretRate = 0;
			for (LotteryMode e : modes) {
				if (e.getLevelMin() > 0 && player.getLevel() < e.getLevelMin()) {
					continue;
				} else if (e.getLevelMax() > 0 && player.getLevel() > e.getLevelMax()) {
					continue;// 等级不符合的跳过
				}
				curretRate += e.getRate();
				if (tmpRate <= curretRate) {
					int curentGoodsId = e.getGoodsId();
					int curentNum = e.getNum();
					if (curentGoodsId == 0 && e.getRateGoodsIds().length > 0) {
						curentGoodsId = e.getRateGoodsIds()[NumberProcesser.mtRand(e.getRateGoodsIds().length) - 1];
					}
					if (curentGoodsId == 0) {
						continue;
					}

					if (awardsMap.containsKey(curentGoodsId)) {
						curentNum += awardsMap.get(curentGoodsId);
					} else {
						if (e.getLevel() > maxLevel) {// 记录获得的等级
							maxLevel = e.getLevel();
						}
					}
					awardsMap.put(curentGoodsId, curentNum);

					break;
				}
			}

		}
		Map<Integer, Integer> bag = player.getDataInfo().getLotteryBag(true);

		StringBuffer sb = new StringBuffer();
		StringBuffer logSB = new StringBuffer();
		StringBuffer chatSB = new StringBuffer();
		int tmpIndex = 0;
		boolean moreLog = false;

		for (Map.Entry<Integer, Integer> entry : awardsMap.entrySet()) {
			int goodsId = entry.getKey();
			int goodsNum = entry.getValue();
			GoodsMode goodsMode = Context.getGoodsServer().getModeById(goodsId);
			if (goodsMode == null) {
				continue;
			}
			int finalNum = goodsNum;
			if (bag.containsKey(goodsId)) {
				finalNum += bag.get(goodsId);
			}
			if (isFirst) {
				Context.getGoodsServer().giveGoodsBing(player.getPlayerId(), goodsId, finalNum, 1);
			} else {
				bag.put(goodsId, finalNum);
			}

			if (maxLevel == 0 && goodsMode.getColor() >= 3) {
				maxLevel = 1;
			}

			tmpIndex++;
			if (tmpIndex > 1) {
				sb.append(",");
			}
			sb.append(goodsMode.getName()).append("/").append(goodsNum).append("/").append(goodsMode.getColor());
			logSB.append(goodsMode.getName()).append("/").append(goodsNum);

			if (goodsMode.getColor() >= 3) {
				if (chatSB.length() > 0) {
					chatSB.append(",");
				}
				chatSB.append(LangUtil.makeHtml(goodsMode.getColor(), goodsMode.getName()));
			}

			if (logSB.toString().getBytes(Constants.charset).length >= 400) {
				moreLog = true;
				LogServer.recordLog(player, ConstantsLog.goods, 70014, type, donType, donNums, costGold, useTools, moreLog, logSB.toString());
				logSB.delete(0, logSB.length());
			}
		}
		if (isFirst) {
			player.getDataInfo().intDataSet(ConstantsIntKey.firstLty, 1);
		}
		
		// 记录晏请神丐次数 结束：202-11-13
//		player.getDataInfo().getEveryDay().intDataAlter(ConstantsDayIntKey.tbl, awardTimesArr[donType]);
		
		player.commitSync();
		player.getDataInfo().commitSync();

		if (type == 1) {
			Context.getTaskServer().notifyToSpark(player.getPlayerId(), ConstantsTask.spark26Lottery, 1);
		}

		lotteryManager.isertLog(type, player.getPlayerId(), player.getPlayerName(), donType, awardTimes, maxLevel, sb.toString(), allGold);
		LogServer.recordLog(player, ConstantsLog.goods, 70014, type, donType, donNums, costGold, useTools, moreLog, logSB.toString());

		String message;
		if (chatSB.length() > 0) {
			message = LanguageLib.get("lottery.chat.suc", player.getPlayerName(), chatSB.toString());
			// message = LanguageLib.get("lottery.chat.suc",
			// LangUtil.makeNameLink(player), chatSB.toString());
		} else {
			message = LanguageLib.get("lottery.chat.info", player.getPlayerName());
			// message = LanguageLib.get("lottery.chat.info",
			// LangUtil.makeNameLink(player));
		}

		ChatMain.systemMessage(message);

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("type", type);
		map.put("donType", donType);
		map.put("donNums", donNums);
		map.put("awards", sb.toString());
		map.put("gold", player.getGold());
		map.put("goldBing", player.getGoldBing());
		map.put("costGold", costGold);
		map.put("useTools", useTools);
		map.put("bagNum", bag.size());

		if (isFirst) {
			return ResponseMessage.ticpMsg(LanguageLib.get("lottery.first.suc"), map);
		} else {
			return ResponseMessage.getSuccMessage(map);
		}
	}

	/**
	 * 显示我的麻布袋
	 * 
	 * @param session
	 * @return
	 */
	public ResponseMessage showBag(Session session) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Map<Integer, Integer> bag = player.getDataInfo().getLotteryBag(false);
		if (bag == null || bag.isEmpty()) {
			return ResponseMessage.getFailMessage(false);
		}
		List<GoodsVO> goods = new LinkedList<GoodsVO>();
		for (Map.Entry<Integer, Integer> entry : bag.entrySet()) {
			int goodsId = entry.getKey();
			int num = entry.getValue();
			GoodsMode goodsMode = Context.getGoodsServer().getModeById(goodsId);
			if (goodsMode == null) {
				continue;
			}
			GoodsVO vo = new GoodsVO(goodsId, player.getPlayerId(), 0);
			vo.setStackNum(num);
			goods.add(vo);

		}

		return ResponseMessage.getSuccMessage(goods);
	}

	/**
	 * 收取物品
	 * 
	 * @param session
	 * @param gird
	 * @param isAll
	 * @return
	 */
	public ResponseMessage gotBag(Session session, int gird, boolean isAll) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Map<Integer, Integer> bag = player.getDataInfo().getLotteryBag(false);
		if (bag == null || bag.isEmpty()) {
			return null;
		}
		if (!isAll && !bag.containsKey(gird)) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		boolean moreLog = false;
		synchronized (bag) {
			int needSize = 0;

			if (isAll) {
				for (Map.Entry<Integer, Integer> entry : bag.entrySet()) {
					GoodsMode goodsMode = Context.getGoodsServer().getModeById(entry.getKey());
					if (goodsMode == null) {
						continue;
					}
					sb.append(goodsMode.getName()).append("*").append(entry.getValue()).append(",");
					needSize += NumberProcesser.ceil(entry.getValue(), goodsMode.getMaxStack());
					if (sb.toString().getBytes(Constants.charset).length >= 400) {
						moreLog = true;
						LogServer.recordLog(player, ConstantsLog.goods, 70015, sb.toString(), moreLog);
						sb.delete(0, sb.length());
					}
				}
			} else {
				GoodsMode goodsMode = Context.getGoodsServer().getModeById(gird);
				if (goodsMode == null) {
					return null;
				}
				sb.append(goodsMode.getName()).append("*").append(bag.get(gird)).append("");
				needSize += NumberProcesser.ceil(bag.get(gird), goodsMode.getMaxStack());
			}
			if (!player.getPlayerBoxs().checkBlack(needSize)) {
				return ResponseMessage.getFailMessage(needSize);
			}

			if (isAll) {
				try {
					for (Map.Entry<Integer, Integer> entry : bag.entrySet()) {
						Context.getGoodsServer().giveGoods(player.getPlayerId(), entry.getKey(), entry.getValue());
					}
				} catch (Exception e) {
					e.printStackTrace();
				}

				bag.clear();
			} else {
				int nums = bag.get(gird);
				bag.remove(gird);
				Context.getGoodsServer().giveGoods(player.getPlayerId(), gird, nums);
			}

		}
		player.getDataInfo().commitSync();
		LogServer.recordLog(player, ConstantsLog.goods, 70015, sb.toString(), moreLog);

		return ResponseMessage.getSuccMessage(true);
	}

	/**
	 * 一键卖出
	 * 
	 * @param session
	 * @param gird
	 * @param isAll
	 * @return
	 */
	public ResponseMessage sellBag(Session session) {

		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		Map<Integer, Integer> bag = player.getDataInfo().getLotteryBag(false);
		if (bag == null || bag.isEmpty()) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		int gotAsset = 0;
		boolean moreLog = false;
		synchronized (bag) {
			for (Map.Entry<Integer, Integer> entry : bag.entrySet()) {
				GoodsMode goodsMode = Context.getGoodsServer().getModeById(entry.getKey());
				if (goodsMode == null) {
					continue;
				}
				gotAsset += goodsMode.getNpcRecover() * entry.getValue();
				sb.append(goodsMode.getName()).append("*").append(entry.getValue()).append(",");

				if (sb.toString().getBytes(Constants.charset).length >= 400) {
					moreLog = true;
					LogServer.recordLog(player, ConstantsLog.goods, 70016, gotAsset, sb.toString(), moreLog);
					sb.delete(0, sb.length());
				}
			}
			bag.clear();
		}
		LogServer.recordLog(player, ConstantsLog.goods, 70016, gotAsset, sb.toString(), moreLog);
		player.alterAsset(gotAsset);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("asset", player.getAsset());
		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 嘉年华显示
	 * 
	 * @param session
	 * @return
	 */
	public ResponseMessage carnivalShow(Session session) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());

		Collection<CarnivalConfig> modes = CarnivalConfig.getAll();
		List<GoodsVO> goods = new LinkedList<GoodsVO>();
		for (CarnivalConfig e : modes) {
			GoodsMode goodsMode = Context.getGoodsServer().getModeById(e.getGoodsId());
			if (goodsMode == null) {
				continue;
			}
			GoodsVO vo = goodsMode.toGoodsVO();
			vo.setStackNum(e.getNum());
			goods.add(vo);
		}

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("goods", goods);
		map.put("free", ConstantsModel.carnivalFree - player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.carFree));
		map.put("assetPool", ActivitySerialize.getInstance().getCarnivalAsset());
		long awarder = ActivitySerialize.getInstance().getCarivalAwarder();
		if (awarder > 0) {
			Player playerAwarder = Context.getPlayerServer().getByPlayerId(awarder);
			map.put("awarderName", playerAwarder.getPlayerName());
			map.put("awarderId", playerAwarder.getPlayerId());
			map.put("awarderAsset", ActivitySerialize.getInstance().getCarivalAwardAsset());
		}

		QQDC.getInstance().logClick(player, LogFieldType.carnival);

		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 嘉年华游玩
	 * 
	 * @param session
	 * @return
	 */
	public ResponseMessage carnivalPlay(Session session) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		int carFree = player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.carFree);
		boolean useFree = carFree < ConstantsModel.carnivalFree;
		if (!useFree && player.getAsset() < ConstantsModel.carnivalAsset) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.asset"));
		}
		if (!player.getPlayerBoxs().checkBlack()) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.player.boxmin", 1));
		}
		if (useFree) {
			player.getDataInfo().getEveryDay().intDataSet(ConstantsDayIntKey.carFree, carFree + 1);
		} else {
			player.alterAsset(-ConstantsModel.carnivalAsset);
		}
		int currentRate = NumberProcesser.mtRand(10000);
		int tmpRate = 0;
		Collection<CarnivalConfig> modes = CarnivalConfig.getAll();
		CarnivalConfig awardConfig = null;
		for (CarnivalConfig e : modes) {
			tmpRate += e.getRate();
			if (currentRate <= tmpRate) {
				awardConfig = e;
				break;
			}
		}
		StringBuilder sb = new StringBuilder();
		int gotAsset = 0;
		GoodsMode awardMode = null;
		if (awardConfig.getAssetAward() > 0) {

			if (awardConfig.getAssetAward() > 100) {
				gotAsset = awardConfig.getAssetAward();
			} else {
				gotAsset = ActivitySerialize.getInstance().getCarnivalAsset() / 100 * awardConfig.getAssetAward();
				ChatMain.systemMessageDelay(LanguageLib.get("lottery.carnival.asset", player.getPlayerName(), gotAsset), 5);

			}
			if (awardConfig.getAssetAward() == 100) {
				ActivitySerialize.getInstance().setCarnivalAsset(ConstantsModel.carnivalAssetInit);
				ActivitySerialize.getInstance().setCarivalAwarder(session.getUid());
				ActivitySerialize.getInstance().setCarivalAwardAsset(gotAsset);
				// 公告

			} else {
				ActivitySerialize.getInstance().alterCarnivalAsset(-gotAsset);
			}
			ActivitySerialize.getInstance().commitSync();
			player.alterAsset(gotAsset);

			sb.append(LanguageLib.get("comm.sys.asset")).append("/").append(gotAsset).append("/").append(awardConfig.getLevel());
		} else {
			int gotGoodsId = 0;

			if (awardConfig.getRateIdsArray() != null) {
				gotGoodsId = NumberProcesser.getRateOne(awardConfig.getRateIdsArray());
			} else {
				gotGoodsId = awardConfig.getGoodsId();
			}
			awardMode = Context.getGoodsServer().getModeById(gotGoodsId);
			Context.getGoodsServer().giveGoodsBing(session.getUid(), gotGoodsId, awardConfig.getNum(), 1);
			if (awardMode.getColor() >= 3) {
				ChatMain.systemMessageDelay(
						LanguageLib.get("lottery.carnival.goods", player.getPlayerName(), LangUtil.makeHtml(awardMode.getColor(), awardMode.getName())), 5);
			}
			sb.append(awardMode.getName()).append("/").append(awardConfig.getNum()).append("/").append(awardMode.getColor());

		}
		if (!useFree) {
			ActivitySerialize.getInstance().alterCarnivalAsset(ConstantsModel.carnivalAsset / 2);
		}

		player.commitSync();
		String gotAward = awardMode == null ? null : awardMode.getName();
		
		//加入到每日奖励
		player.getDataInfo().getEveryDay().finishDailyItem(ConstantsDailyItem.joinBudoFiestaItem);

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("assetPool", ActivitySerialize.getInstance().getCarnivalAsset());
		map.put("asset", player.getAsset());
		map.put("gotAsset", gotAsset);
		map.put("gotAward", gotAward);
		map.put("gotNum", awardConfig.getNum());
		map.put("gotId", awardConfig.getId());
		map.put("free", ConstantsModel.carnivalFree - player.getDataInfo().getEveryDay().intDataGet(ConstantsDayIntKey.carFree));
		if (awardConfig.getAssetAward() == 100) {
			map.put("awarderName", player.getPlayerName());
			map.put("awarderId", player.getPlayerId());
			map.put("awarderAsset", gotAsset);

		}
		lotteryManager.isertLog(51, player.getPlayerId(), player.getPlayerName(), 1, 1, awardConfig.getLevel(), sb.toString(), 0);
		if (awardConfig.getLevel() >= 2) {//2级以上才更新缓存
			lotteryManager.getCarnivalLogsCache(true);
		}

		LogServer.recordLog(player, ConstantsLog.goods, 70101, useFree ? 0 : ConstantsModel.carnivalAsset, gotAward, awardConfig.getNum(), gotAsset);

		return ResponseMessage.getSuccMessage(map);
	}

}
